﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Data;
using System.Data.Objects;
using Fujitsu.JiraAnalysis.Common;

namespace Fujitsu.JiraAnalysis.DAL
{
    public class WorklogStorage
    {
        public IEventLog EventLog = new EventLogWrapper();

        public IEnumerable<Worklog> GetWorklogsForIssue(int issueId)
        {
            using (var db = new JiraAnalysisDBEntities())
            {
                return db.Worklog.Where(w => w.IssueID == issueId).ToList();
            }
        }
        public int? AddWorklog(Worklog dbWorklog)
        {
            using (var db = new JiraAnalysisDBEntities())
            {
                try
                {
                    db.AddToWorklog(dbWorklog);
                    db.SaveChanges();
                }
                catch (OptimisticConcurrencyException)
                {
                    db.Refresh(RefreshMode.ClientWins, dbWorklog);
                    db.SaveChanges();
                }
                catch (DataException ex)
                {
                    EventLogger.CreateInstance(EventLog).LogWriteError(string.Concat("Can't add worklog to DB.", Environment.NewLine, ex.StackTrace));
                    return null;
                }

                return dbWorklog.ID;
            }
        }

        public void UpdateWorklog(Worklog dbWorklog)
        {
            using (var db = new JiraAnalysisDBEntities())
            {
                var worklogToUpdate = db.Worklog.FirstOrDefault(i => i.ID == dbWorklog.ID);

                if (worklogToUpdate != null)
                {
                    worklogToUpdate.AuthorID = dbWorklog.AuthorID;
                    worklogToUpdate.Body = dbWorklog.Body;
                    worklogToUpdate.Created = dbWorklog.Created;
                    worklogToUpdate.UpdateAuthorID = dbWorklog.UpdateAuthorID;
                    worklogToUpdate.Updated = dbWorklog.Updated;
                    worklogToUpdate.StartDate = dbWorklog.StartDate;
                    worklogToUpdate.TimeWorked = dbWorklog.TimeWorked;
                }

                try
                {
                    db.SaveChanges();
                }
                catch (OptimisticConcurrencyException)
                {
                    db.Refresh(RefreshMode.ClientWins, worklogToUpdate);
                    db.SaveChanges();
                }
                catch (DataException ex)
                {
                    EventLogger.CreateInstance(EventLog).LogWriteError(string.Concat("Can't update worklog in DB.", Environment.NewLine, ex.StackTrace));
                }
            }
        }

        public void DeleteWorklog(int worklogId)
        {
            using (var db = new JiraAnalysisDBEntities())
            {
                var dbWorklog = db.Worklog.FirstOrDefault(w => w.ID == worklogId);
                if (dbWorklog != null)
                {
                    try
                    {
                        db.Worklog.DeleteObject(dbWorklog);
                        db.SaveChanges();
                    }
                    catch (OptimisticConcurrencyException)
                    {
                        db.Refresh(RefreshMode.ClientWins, dbWorklog);
                        db.SaveChanges();
                    }
                    catch (DataException ex)
                    {
                        EventLogger.CreateInstance(EventLog).LogWriteError(string.Concat("Can't delete worklog from DB.", Environment.NewLine, ex.StackTrace));
                    }
                }
            }
        }

        public Worklog GetWorklogForIssue(int issueId, string jiraWorklogId)
        {
            using (var db = new JiraAnalysisDBEntities())
            {
                return db.Worklog.FirstOrDefault(w => w.IssueID == issueId && w.JiraWorklogID == jiraWorklogId);
            }
        }

        public IEnumerable<int> GetWorklogIdsToBeDeleted(int issueId, List<string> jiraWorklogIds)
        {
            using (var db = new JiraAnalysisDBEntities())
            {
                return (from worklog in db.Worklog
                        where worklog.IssueID == issueId && !jiraWorklogIds.Any(w => w == worklog.JiraWorklogID)
                        select worklog.ID).ToList();
            }
        }
    }
}
